﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;

namespace JiveMessenger.Utilities
{
    public class Win32
    {

        #region image preview api

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetCursorPos(ref W32Point pt);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetMonitorInfo(IntPtr hMonitor, ref W32MonitorInfo lpmi);

        [DllImport("user32.dll")]
        internal static extern IntPtr MonitorFromPoint(W32Point pt, uint dwFlags);
        #endregion

        #region window api
        internal const uint GW_HWNDNEXT = 2;

        [DllImport("User32")]
        internal static extern IntPtr GetTopWindow(IntPtr hWnd);
        [DllImport("User32")]
       internal static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);


        public static ArrayList GetAllWindows()
        {
            var windowHandles = new ArrayList();
            EnumedWindow callBackPtr = GetWindowHandle;
            EnumWindows(callBackPtr, windowHandles);

            foreach (IntPtr windowHandle in windowHandles.ToArray())
            {
                EnumChildWindows(windowHandle, callBackPtr, windowHandles);
            }

            return windowHandles;
        }

        private delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList lParam);

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumChildWindows(IntPtr window, EnumedWindow callback, ArrayList lParam);

        private static bool GetWindowHandle(IntPtr windowHandle, ArrayList windowHandles)
        {
            windowHandles.Add(windowHandle);
            return true;
        }


        #endregion


        #region Window Flashing API Stuff
        // ReSharper disable UnusedMember.Local
        // ReSharper disable InconsistentNaming
        internal const UInt32 FLASHW_STOP = 0; //Stop flashing. The system restores the window to its original state.


        internal const UInt32 FLASHW_CAPTION = 1; //Flash the window caption.

        internal const UInt32 FLASHW_TRAY = 2; //Flash the taskbar button.
        internal const UInt32 FLASHW_ALL = 3; //Flash both the window caption and taskbar button.
        internal const UInt32 FLASHW_TIMER = 4; //Flash continuously, until the FLASHW_STOP flag is set.
        internal const UInt32 FLASHW_TIMERNOFG = 12; //Flash continuously until the window comes to the foreground.


        // ReSharper restore InconsistentNaming
        // ReSharper restore UnusedMember.Local
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

        #endregion
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct FLASHWINFO
    {
        public UInt32 cbSize; //The size of the structure in bytes.
        public IntPtr hwnd; //A Handle to the Window to be Flashed. The window can be either opened or minimized.
        public UInt32 dwFlags; //The Flash Status.
        public UInt32 uCount; // number of times to flash the window
        public UInt32 dwTimeout; //The rate at which the Window is to be flashed, in milliseconds. If Zero, the function uses the default cursor blink rate.
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct W32Point
    {
        public int X;
        public int Y;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct W32MonitorInfo
    {
        public int Size;
        public W32Rect Monitor;
        public W32Rect WorkArea;
        public uint Flags;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct W32Rect
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

}
